package ai.moran.demo.stateMachine.test;


import ai.moran.demo.enums.TurnstileEvents;
import ai.moran.demo.enums.TurnstileStates;
import ai.moran.demo.utils.ModelStateMachineUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.StateMachineBuilder;
import org.springframework.stereotype.Component;

import java.util.EnumSet;

/**
 * @author zhuhaitao
 * @email zhuhaitao@imoran.net
 * @date 2020/8/25 4:33 下午
 */

@Component
public class TurnstileStateMachineConfig {

    public  StateMachine<TurnstileStates, TurnstileEvents> buildMachine(BeanFactory beanFactory) throws Exception {
        StateMachineBuilder.Builder<TurnstileStates, TurnstileEvents> builder = StateMachineBuilder.builder();

        //配置stateMachine
        builder.configureConfiguration()
                .withConfiguration()
                .machineId("myMachineId")
                .beanFactory(beanFactory)
                .machineId("turnstileMachine");

        //初始化状态值
        builder.configureStates()
                .withStates()
                .initial(TurnstileStates.Locked)
                .states(EnumSet.allOf(TurnstileStates.class));

        builder.configureTransitions()
                .withExternal()
                .source(TurnstileStates.Unlocked).target(TurnstileStates.Locked)
                .event(TurnstileEvents.COIN)
                .action(customerPassAndLock())
                .and()
                .withExternal()
                .source(TurnstileStates.Locked).target(TurnstileStates.Unlocked)
                .event(TurnstileEvents.PUSH)
                .action(turnstileUnlock());

        return builder.build();
    }

    public StateMachine<TurnstileStates, TurnstileEvents> buildWithState(BeanFactory beanFactory, TurnstileStates status) throws Exception {
        StateMachine<TurnstileStates, TurnstileEvents> stateMachine = buildMachine(beanFactory);
        ModelStateMachineUtils.setCurrentState(stateMachine, status);
        return stateMachine;
    }


    public Action<TurnstileStates, TurnstileEvents> turnstileUnlock() {
        return context -> System.out.println("解锁旋转门，以便游客能够通过" );
    }

    public Action<TurnstileStates, TurnstileEvents> customerPassAndLock() {
        return context -> System.out.println("当游客通过，锁定旋转门" );
    }

}
